home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’91 / MS Works Merge Enhancer / getWorks.cp < prev    next >
Encoding:
Text File  |  1991-06-20  |  7.1 KB  |  290 lines  |  [TEXT/MPS ]

  1. #include    <types.h>
  2. #include    <Quickdraw.h>
  3. //#include    <windows.h>
  4. #include    <memory.h>
  5. //#include    <controls.h>
  6. //#include    <Dialogs.h>
  7. #include    <ToolUtils.h>
  8. #include    <Packages.h>
  9. #include     <String.h>
  10. #include     <Strings.h>
  11. //#include     <Errors.h>
  12. #include     <Resources.h>
  13. #include     <files.h>
  14.  
  15. #include "THyperXCmd.h"
  16.  
  17. Handle BuildPathname (TXCMDBlock *myParamPtr, StringPtr fName, short vRefNum);
  18.  
  19. pascal void getWorks ( TXCMDBlock *myParamPtr )
  20. {
  21.  
  22.     SFTypeList        typeList;
  23.     SFReply            reply;
  24.     Point            where;
  25.     OSErr            theErr;
  26.     long            fileSize;
  27.     Handle            fileNameHandle=nil;
  28.     long            theOffset;
  29.     
  30.     const OSType    AWDBtype=0x41574442;
  31.     const Size        maxBlank=10;
  32.  
  33.  
  34. /*
  35.   check for the correct number of parameters
  36. */
  37.  
  38.     if ( !myParamPtr->informArgNums((char *) "getWorks", 3) )
  39.     {
  40.         return;
  41.     }
  42.  
  43. /*
  44.   Set up the parameter block. If the parameter block can be recovered from
  45.   the global myParamBlock, use it, otherwise, set up a new one and get the
  46.   file.
  47. */
  48.  
  49.     ParmBlkPtr myParamBlock= (ParmBlkPtr) myParamPtr->RecoverLongGlobal((StringPtr) "\pmyParamBlock");
  50.     if (!myParamBlock)
  51.     {
  52.         myParamBlock=(ParmBlkPtr)NewPtr(sizeof(FileParam));
  53.         if (!myParamBlock)
  54.         {
  55.             myParamPtr->SignalFatalError((char *) "\pNot enough memory for file operations.");
  56.             return;
  57.         }
  58.  
  59.         myParamBlock->ioParam.ioCompletion=0;
  60.  
  61. /*
  62.   Get the filename from the specified field. The value passed is the id of
  63.   a card field which contains the full pathname to the desired file.
  64.   If a file is found with that name, we use that file, otherwise, return the
  65.   error as the XFCN result. If the field is empty, we call SFGet to get a
  66.   filename and recover the full pathname to the file, which we place in
  67.   the specified background field.
  68. */
  69.  
  70.         short listFieldID= (short) myParamPtr->RecoverLongArg(0);
  71.         fileNameHandle=myParamPtr->GetFieldByID(true, listFieldID);
  72.         HLock(fileNameHandle);
  73.         
  74.         if (strlen(*fileNameHandle))
  75.         {
  76.             c2pstr(*fileNameHandle);
  77.             myParamBlock->fileParam.ioNamePtr=(StringPtr)*fileNameHandle;
  78.             myParamBlock->fileParam.ioVRefNum=0;
  79.             myParamBlock->fileParam.ioFRefNum=0;
  80.             myParamBlock->fileParam.ioFDirIndex=0;
  81.             
  82.             if (theErr=PBGetFInfo(myParamBlock, false))
  83.             {
  84.                 myParamPtr->SignalFileErr(theErr);
  85.                 return;
  86.             }
  87.             else if ((myParamBlock->fileParam.ioFlFndrInfo.fdType)!=AWDBtype)
  88.             {
  89.                 myParamPtr->SignalFatalError((char *) "\pFile not Works database!");
  90.                 return;
  91.             }
  92.             else
  93.             {
  94.                 fileSize=myParamBlock->fileParam.ioFlLgLen;
  95.             }
  96.             DisposHandle(fileNameHandle);
  97.  
  98.         }
  99.         else
  100.         {
  101.             typeList[0]=AWDBtype;
  102.             where.v=50;
  103.             where.h=50;
  104.             SFGetFile(where, "\pSelect file to load", nil, 1, typeList, nil, &reply);
  105.             if (reply.good)
  106.             {
  107.                 myParamBlock->ioParam.ioVRefNum=reply.vRefNum;
  108.                 myParamBlock->ioParam.ioNamePtr=(StringPtr)&(reply.fName);
  109.                 Handle fsHandle=BuildPathname (myParamPtr, reply.fName, reply.vRefNum);
  110.                 if (fsHandle)
  111.                     myParamPtr->SetFieldByID(true, listFieldID, fsHandle);
  112.                 else
  113.                     return;
  114.                 c2pstr((char *)&(reply.fName));
  115.             }
  116.             else
  117.             {
  118.                 myParamPtr->SignalFatalError( (char *) "\pFile not specified.");
  119.                 return;
  120.             }
  121.         }
  122.  
  123. /*
  124.   Open the file for readOnly access. If we got the file name from SFFile,
  125.   get the file size (We already got the file size for the explicitly named
  126.   file with the call to PBGetFInfo)
  127. */
  128.     
  129.         myParamBlock->ioParam.ioVersNum=0;
  130.         myParamBlock->ioParam.ioPermssn=fsRdPerm;
  131.         myParamBlock->ioParam.ioMisc=0;
  132.         if (theErr=PBOpen(myParamBlock, false))
  133.         {
  134.             myParamPtr->SignalFileErr(theErr);
  135.             return;
  136.         }
  137.         if (!fileSize)
  138.         {
  139.             if (theErr=PBGetEOF(myParamBlock, false))
  140.             {
  141.                 myParamPtr->SignalFileErr(theErr);
  142.                 return;
  143.             }
  144.             fileSize=(long)myParamBlock->ioParam.ioMisc;
  145.         }
  146.         myParamPtr->SetLongGlobal((StringPtr) "\pmyFileSize", fileSize);
  147.         myParamPtr->SetLongGlobal((StringPtr) "\pmyParamBlock", (long) myParamBlock);
  148.  
  149.     }
  150.     
  151.  
  152. //  Position the file to the start of the database data and read the length word
  153.  
  154.     fileSize = myParamPtr->RecoverLongGlobal((StringPtr) "\pmyFileSize");
  155.     theOffset= myParamPtr->RecoverLongGlobal((StringPtr) "\pmyOffset");
  156.  
  157.     if (!theOffset)
  158.         theOffset=0x058F;
  159.     short theLength=0;
  160.     long theCount=2;
  161.     myParamBlock->ioParam.ioBuffer=(Ptr)&theLength;
  162.     myParamBlock->ioParam.ioReqCount=theCount;
  163.     myParamBlock->ioParam.ioPosMode=fsFromStart;
  164.     myParamBlock->ioParam.ioPosOffset=theOffset;
  165.     if (theErr=PBRead(myParamBlock, false))
  166.     {
  167.         myParamPtr->SignalFileErr(theErr);
  168.         return;
  169.     }
  170.     
  171.     theOffset+=theCount;
  172.     
  173.     if (theLength==0x03F6)
  174.     {
  175.         do
  176.             {
  177.                 theOffset+=theLength;
  178.                 long theCount=2;
  179.                 myParamBlock->ioParam.ioBuffer=(Ptr)&theLength;
  180.                 myParamBlock->ioParam.ioReqCount=theCount;
  181.                 myParamBlock->ioParam.ioPosMode=fsFromStart;
  182.                 myParamBlock->ioParam.ioPosOffset=theOffset;
  183.                 if (theErr=PBRead(myParamBlock, false))
  184.                 {
  185.                     myParamPtr->SignalFileErr(theErr);
  186.                     return;
  187.                 }
  188.                 theOffset+=theCount;
  189.             }
  190.         while (theLength==0x03F6);
  191.     }
  192.  
  193.     short outField= (short) myParamPtr->RecoverLongArg(2);
  194.     Handle stringHandle=NewHandle((Size) theLength + maxBlank);
  195.     if (theErr=MemError())
  196.     {
  197.         CString ErrorString = CString("Memory error: ") + CString((long)theErr);
  198.         myParamPtr->SignalFatalError(ErrorString);
  199.         return;
  200.     }
  201.     HLock(stringHandle);
  202.     myParamBlock->ioParam.ioBuffer=*stringHandle;
  203.     myParamBlock->ioParam.ioReqCount=theLength-1;
  204.     myParamBlock->ioParam.ioPosMode=fsFromStart;
  205.     myParamBlock->ioParam.ioPosOffset=theOffset;
  206.     if (theErr=PBRead(myParamBlock, false))
  207.     {
  208.         myParamPtr->SignalFileErr(theErr);
  209.         return;
  210.     }
  211.     
  212.     theOffset+=theLength;
  213.     myParamPtr->SetLongGlobal((StringPtr) "\pmyOffset", theOffset);
  214.  
  215. #ifdef debug    
  216.     CString tempString = CString(";dm #") + CString((long) *stringHandle);
  217.     debugstr ((char *) tempString);
  218. #endif
  219.     
  220.     register Ptr myStringPtr = StripAddress(*stringHandle);
  221.     size_t theLen;
  222.     long cumLen=0;
  223.  
  224.     short numBlank;    
  225.     do
  226.     {
  227.         p2cstr((StringPtr)myStringPtr);
  228.         theLen=strlen(myStringPtr);
  229.         myStringPtr[theLen]=(char)0x0D;
  230.         myStringPtr+=theLen+1;
  231.         if ( *myStringPtr == (char)0xFE )
  232.         {
  233.             *(myStringPtr++) = (char)0x0D;
  234.             cumLen++;
  235.             numBlank=*(myStringPtr);
  236.             switch (numBlank)
  237.             {
  238.             case 1:
  239.                 BlockMove(myStringPtr+1,myStringPtr,theLength-cumLen-1);
  240.                 theLength--;
  241.                 cumLen+=1;
  242.                 break;
  243.             case 2:
  244.                 *(myStringPtr++) = (char)0x0D;
  245.                 cumLen+=2;
  246.                 break;
  247.             default:
  248.                 BlockMove(myStringPtr+1,myStringPtr+numBlank,theLength-cumLen-1);
  249.                 numBlank--;
  250.                 theLength+=numBlank-1;
  251.                 cumLen+=numBlank+1;
  252.                 for (short k=0;k<numBlank;k++)
  253.                     *(myStringPtr++) = (char)0x0D;
  254.                 myStringPtr++;
  255.                 break;
  256.             }
  257.         }
  258.         cumLen+=theLen+1;
  259.     }
  260.     while (cumLen<theLength-1);
  261.     *(myStringPtr-1)=(char)0x00;
  262.  
  263.     HUnlock(stringHandle);
  264.     myParamPtr->SetFieldByID(true, outField, stringHandle);
  265.     
  266. /*
  267.   If the second argument is true, or we are on the last record, then close the file,
  268.   otherwise, do not
  269. */
  270.     if ( (myParamPtr->RecoverBooleanArg(1))
  271.         || (theOffset>=fileSize-1) )
  272.     {
  273.         if (theErr=PBClose(myParamBlock, false))
  274.         {
  275.             myParamPtr->SignalFileErr(theErr);
  276.             return;
  277.         }
  278.         if (myParamBlock)
  279.             DisposPtr((Ptr)myParamBlock);
  280.         myParamPtr->SetLongGlobal((StringPtr) "\pmyParamBlock", (long) 0);
  281.         myParamPtr->SetLongGlobal((StringPtr) "\pmyOffset", (long) 0);
  282.         myParamPtr->SignalReturnStatus((StringPtr)"\pEOF");
  283.     }
  284.     else
  285.         myParamPtr->SignalReturnStatus((StringPtr)"\pOK");
  286.     
  287.     return;
  288. }
  289.  
  290.